package com.tomicalab.mobiletoken.ckca;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import iaik.pkcs.pkcs11.wrapper.PKCS11Exception;

import com.tomicalab.mobiletoken.ckca.utils.CertItem;
import com.tomicalab.mobiletoken.ckca.utils.Constant;
import com.tomicalab.mobiletoken.ckca.utils.CustomProgressDialog;
import com.tomicalab.mobiletoken.ckca.utils.P11Other;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.ContactsContract.CommonDataKinds.Im;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

public class Certificate extends Activity{
	
	private EditText etPin;
	private ImageButton iBLogin;
	private Context context;
	private Resources res;
	
	private LinearLayout LL_Login;
	private LinearLayout LL_Cert;
	
	private ImageView iVLogout;
	private ListView lvCertView;
	
	private static CustomProgressDialog progressDialog;
	private static handler handler;
	
	public class handler extends Handler {
		String pin;
		public void sleep(long delayMillis, int msgID, Object obj) {
            this.removeMessages(msgID);
            Message msg = new Message();
            msg.what = msgID;
            msg.obj  = obj;
            sendMessageDelayed(msg, delayMillis);
        }
		public void sleep(long delayMillis, int msgID, Object obj, String pin) {
            this.removeMessages(msgID);
            Message msg = new Message();
            msg.what = msgID;
            msg.obj  = obj;
            this.pin = pin;
            sendMessageDelayed(msg, delayMillis);
        }
		
		public void handleMessage(Message msg) {
			switch(msg.what) {
			case Constant.SHOWPROGRESSDIALOG:
				Log.e(Constant.Debug, "SHOWPROGRESSDIALOG");
				progressDialog.show();
				super.handleMessage(msg);
				break;
			case Constant.CLOSEPROGRESSDIALOG:
				progressDialog.dismiss();
				super.handleMessage(msg);
				break;
			case Constant.SHOWERRINFO:
				if (null != msg.obj)
				{
					if(msg.obj.toString().compareTo(res.getString(R.string.inform_handset_connectfail))==0)
					{
						String title, button;
			    		button = res.getString(R.string.inform_button_OK);
						title = res.getString(R.string.inform_title);
						new Builder(context)
				    	.setTitle(title)
				    	.setMessage(msg.obj.toString())
				    	.setPositiveButton(button, new DialogInterface.OnClickListener() {
							
							@Override
							public void onClick(DialogInterface arg0, int arg1) {
								finish();
							}
						}).show();
					}
					else
						Constant.showMessage(msg.obj.toString(), context, res);
				}
				super.handleMessage(msg);
				break;
			case Constant.LOGIN:
				login(pin);
				super.handleMessage(msg);
				break;
			case Constant.GETCERTIFICATEVIEW:
				LL_Login.setVisibility(View.GONE);
				LL_Cert.setVisibility(View.VISIBLE);
				getViewCertificate();
				super.handleMessage(msg);
				break;
			}
			
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_certificate);
		Log.i(Constant.Debug, "omCreate Certificate");
		context = this;
		res = this.getResources();
		
		LL_Login = (LinearLayout) findViewById(R.id.viewLogin);
		LL_Cert = (LinearLayout) findViewById(R.id.viewCertificate);
		
		iVLogout = (ImageView) findViewById(R.id.iv_logout);
		
		lvCertView = (ListView) findViewById(R.id.lv_cer);
		
		etPin = (EditText) findViewById(R.id.et_login_pin);
		iBLogin = (ImageButton) findViewById(R.id.btn_login_ok);
		
		progressDialog = new CustomProgressDialog(context);
		progressDialog.setCancelable(false);
		handler = new handler();
		
		iBLogin.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				if(P11Other.isTokenPlugned == 0)
				{
					Constant.showMessage(res.getString(R.string.inform_handset_plugout), context, res);
				}
				else
				{
					if(P11Other.isLoadlib == 0)
					{
						Constant.showMessage(res.getString(R.string.inform_handset_loadLib), context, res);
					}
					else
					{
						String pin = etPin.getText().toString();
						Constant.hideSoftKeyboard(Certificate.this, arg0);
						if(pin.length() == 0)
						{
							Constant.showMessage(res.getString(R.string.inform_login_input_notnull), context, res);
						}
						else
						{
							progressDialog.setShowInfo(res.getString(R.string.inform_login_wait));
							handler.sleep(0, Constant.SHOWPROGRESSDIALOG, "");
							handler.sleep(10, Constant.LOGIN, "", pin);
							etPin.setText("");
//							try {
//								P11Other.deleteCertificateByID("39313941363736312D384444432D343935392D394230302D3043303037343432413831353100");
//							} catch (PKCS11Exception e) {
//								e.printStackTrace();
//							}
						}
					}
				}
			}
		});
		
		iVLogout.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View arg0) {
				LL_Login.setVisibility(View.VISIBLE);
				LL_Cert.setVisibility(View.GONE);
				try {
					P11Other.logout();
				} catch (PKCS11Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	@Override
	protected void onResume() {
		super.onResume();
		Log.i(Constant.Debug, "onResume Certificate");
	}
	private void login(final String pin)
	{
		new Thread() {
			public void run() {
				try {
					int rv = P11Other.loginUser(pin);
					handler.sleep(0, Constant.CLOSEPROGRESSDIALOG, "");
					
					if(rv == 0)
					{
						handler.sleep(0, Constant.GETCERTIFICATEVIEW, "");
						
					} else if(rv == 1)
					{
						handler.sleep(0, Constant.SHOWERRINFO, res.getString(R.string.inform_login_fail));
					}
					else
					{
						handler.sleep(0, Constant.SHOWERRINFO, res.getString(R.string.inform_unblock_generalerror));
					}
					
				} catch (PKCS11Exception e) {
					e.printStackTrace();
					handler.sleep(0, Constant.SHOWERRINFO, res.getString(R.string.inform_unblock_generalerror));
				}
			}
		}.start();
	}
	
	private void getViewCertificate()
	{
		ArrayList<CertItem> itemsCert = new ArrayList<CertItem>();
		CertItem[] certArray = null;
		try {
			certArray = P11Other.getAllCerts();
		} catch (PKCS11Exception e) {
			e.printStackTrace();
		}
		if(certArray != null)
		{
			for(int i=0; i<certArray.length; i++)
			{
				itemsCert.add(certArray[i]);
			}
			ItemCertAdapter itemsCertAdapter = new ItemCertAdapter(context, R.layout.item_detail_cert, itemsCert);
			lvCertView.setAdapter(itemsCertAdapter);
			int totalHeight = 0;
	        for (int i = 0; i < itemsCertAdapter.getCount(); i++) {
	        	View listItem = itemsCertAdapter.getView(i, null, lvCertView);
	        	listItem.measure(0, 0);
	        	totalHeight += listItem.getMeasuredHeight();
	        }
	        ViewGroup.LayoutParams params = lvCertView.getLayoutParams();
	        params.height = totalHeight + (lvCertView.getDividerHeight() * (itemsCertAdapter.getCount() - 1));
	        lvCertView.setLayoutParams(params);
		}
	}
	
	public class ItemCertAdapter extends ArrayAdapter<CertItem> {

		private	ArrayList<CertItem> item;
		public LayoutInflater inflater;
		public int resource;
		Resources res;
		
		public ItemCertAdapter(Context context, int textViewResourceId, ArrayList<CertItem> objects) {
			super(context, textViewResourceId, objects);
			// TODO Auto-generated constructor stub
			inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			this.res = context.getResources();
			this.resource = textViewResourceId;
			this.item = objects;
		}

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return item.size();
		}

		@Override
		public View getView(final int position, View convertView, ViewGroup parent) {
			// TODO Auto-generated method stub
			View v;
            if (convertView == null) {
                v = inflater.inflate(resource, parent, false);
            } else {
                v = convertView;
            }
            TextView commonName = (TextView)v.findViewById(R.id.tvDetailCert);
            ImageView ivIcon = (ImageView)v.findViewById(R.id.ivDetailCert);
            commonName.setText(item.get(position).getDN());
            ivIcon.setImageDrawable(res.getDrawable(R.drawable.certificate));
            v.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View arg0) {
					// TODO Auto-generated method stub
					AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);

					View view = getLayoutInflater().inflate(R.layout.layout_certificate_detail, null);

					EditText subject = (EditText) view.findViewById(R.id.etSubject);
					subject.setKeyListener(null);
					
					EditText issuer = (EditText) view.findViewById(R.id.etIssuer);
					issuer.setKeyListener(null);
					
					EditText serial = (EditText) view.findViewById(R.id.etSerial);
					serial.setKeyListener(null);
					
					TextView validto = (TextView) view.findViewById(R.id.tvDateValid);
					TextView expiredfrom = (TextView) view.findViewById(R.id.tvDateExpired);
					TextView alg = (TextView) view.findViewById(R.id.tvAlgorithm);
					TextView version = (TextView) view.findViewById(R.id.tvVersion);
					TextView oid = (TextView) view.findViewById(R.id.tvOID);
					
					InputStream inStream = new ByteArrayInputStream(item.get(position).getValue());
					CertificateFactory cf;
					
					X509Certificate x509cer = null;
					try {
						cf = CertificateFactory.getInstance("X.509");
						x509cer = (X509Certificate) cf.generateCertificate(inStream);
					} catch (java.security.cert.CertificateException e) {
						e.printStackTrace();
					}
					
					subject.setText(x509cer.getSubjectDN().getName());
					issuer.setText(x509cer.getIssuerDN().getName());
					version.setText(String.valueOf(x509cer.getVersion()));
					alg.setText(x509cer.getSigAlgName());
					oid.setText(x509cer.getSigAlgOID());
					SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy");
					validto.setText(df.format(x509cer.getNotBefore()));
					expiredfrom.setText(df.format(x509cer.getNotAfter()));
					serial.setText(x509cer.getSerialNumber().toString(16));
			   	    
					alertDialogBuilder.setView(view);
					alertDialogBuilder.show();
				}
			});
			return v;
		}
		
		
	}

}
